﻿namespace ImageProcessing.ImageProcessor
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// add noise class
    /// </summary>
    public static class IMG_AddNoise
    {
        /// <summary>
        /// Adds the salt and pepper.
        /// </summary>
        /// <param name="imgOrg">The img org.</param>
        /// <param name="saltPer">The salt per.</param>
        /// <param name="pepperPer">The pepper per.</param>
        /// <returns>noise image</returns>
        public static Entities.IMG_Image AddSaltAndPepper(Entities.IMG_Image imgOrg, double saltPer, double pepperPer)
        {
            try
            {
                int w = imgOrg.Width;
                int h = imgOrg.Height;
                IMG_PerfectRandom perfectRandom = new IMG_PerfectRandom(w, h);
                int p;
                int numberOfSalt = (int)(w * h * saltPer);
                int numberOfPepper = (int)(w * h * pepperPer);
                for (int i = 0; i < numberOfPepper; i++)
                {
                    p = perfectRandom.IMG_GetNextPerfectRandom();
                    imgOrg.ImagePixels[p] = new Entities.Pixel(0, 0, 0);
                }

                for (int i = 0; i < numberOfSalt; i++)
                {
                    p = perfectRandom.IMG_GetNextPerfectRandom();
                    imgOrg.ImagePixels[p] = new Entities.Pixel(255, 255, 255);
                }

                return imgOrg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Adds the uniform.
        /// </summary>
        /// <param name="imgOrg">The img org.</param>
        /// <param name="percentage">The percentage.</param>
        /// <param name="a">A. value</param>
        /// <param name="b">The b.</param>
        /// <returns>noise image</returns>
        public static Entities.IMG_Image AddUniform(Entities.IMG_Image imgOrg, double percentage, int a, int b)
        {
            try
            {
                bool normalize = false;
                int w = imgOrg.Width;
                int h = imgOrg.Height;
                IMG_PerfectRandom perfectRandom = new IMG_PerfectRandom(w, h);
                int p;
                int numberOfNoise = (int)((1.0 / (b - a)) * w * h * percentage);

                for (int i = a; i < b; i++)
                {
                    for (int j = 0; j < numberOfNoise; j++)
                    {
                        p = perfectRandom.IMG_GetNextPerfectRandom();
                        imgOrg.ImagePixels[p] = new Entities.Pixel(imgOrg.ImagePixels[p].Red + i, imgOrg.ImagePixels[p].Green + i, imgOrg.ImagePixels[p].Blue + i);
                        if (imgOrg.ImagePixels[p].Red > 255 | imgOrg.ImagePixels[p].Green > 255 | imgOrg.ImagePixels[p].Blue > 255)
                        {
                            normalize = true;
                        }
                    }
                }

                if (numberOfNoise <= 0)
                {
                    return imgOrg;
                }

                if (normalize)
                {
                    return ImageProcessor.IMG_Normalize.IMG_NormalizeImage(imgOrg);
                }

                return imgOrg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Adds the gaussian.
        /// </summary>
        /// <param name="imgOrg">The img org.</param>
        /// <param name="percentage">The percentage.</param>
        /// <param name="mu">The mu.</param>
        /// <param name="sigma">The sigma.</param>
        /// <returns>noise image</returns>
        public static Entities.IMG_Image AddGaussian(Entities.IMG_Image imgOrg, double percentage, double mu, double sigma)
        {
            try
            {
                bool normalize = false;
                int w = imgOrg.Width;
                int h = imgOrg.Height;
                IMG_PerfectRandom perfectRandom = new IMG_PerfectRandom(w, h);
                int p;
              
                for (int i = 0; i <= 255; i++)
                {
                    int numberOfNoise = (int)((1.0 / Math.Sqrt(2 * Math.PI * sigma * sigma)) * Math.Exp(-1 * Math.Pow((i - mu), 2) / (2 * sigma * sigma)) * w * h * percentage);
                    for (int j = 0; j < numberOfNoise; j++)
                    {
                        p = perfectRandom.IMG_GetNextPerfectRandom();

                        imgOrg.ImagePixels[p] = new Entities.Pixel(imgOrg.ImagePixels[p].Red + i, imgOrg.ImagePixels[p].Green + i, imgOrg.ImagePixels[p].Blue + i);
                        if (imgOrg.ImagePixels[p].Red > 255 | imgOrg.ImagePixels[p].Green > 255 | imgOrg.ImagePixels[p].Blue > 255)
                        {
                            normalize = true;
                        }
                    }
                }

                if (normalize)
                {
                    return ImageProcessor.IMG_Normalize.IMG_NormalizeImage(imgOrg);
                }

                return imgOrg;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
